/**
 * @file modbus.c - a very simple modbus implentation.
 * @author kuoted (cvsuser@163.com)
 * @brief
 * @version 0.1
 * @date 2024-10-24
 *
 * @copyright Copyright (c) 2024
 *
 */

//  modbus function code
#include <bits/stdint-uintn.h>
#include <stdio.h>
enum {
  ModbusFC_eReadHoldingReg     = 0x03,
  ModbusFC_ePresetSingleReg    = 0x06,
  ModbusFC_ePresetMultipleRegs = 0x10,
};
/*定义Modbus的操作功能码，支持01、02、03、04、05、06、15、16功能码*/
typedef enum {
  /*读线圈状态（读多个输出位的状态）*/
  ModbusFC_eReadCoilStatus = 0x01,
  /*读输入位状态（读多个输入位的状态）*/
  ModbusFC_eReadInputStatus = 0x02,
  /*读保持寄存器（读多个保持寄存器的数值）*/
  ModbusFC_eReadHoldingRegister = 0x03,
  /*读输入寄存器（读多个输入寄存器的数值）*/
  ModbusFC_eReadInputRegister = 0x04,
  /*强制单个线圈（强制单个输出位的状态）*/
  ModbusFC_eWriteSingleCoil = 0x05,
  /*预制单个寄存器（设定一个寄存器的数值）*/
  ModbusFC_eWriteSingleRegister = 0x06,
  /*强制多个线圈（强制多个输出位的状态）*/
  ModbusFC_eWriteMultipleCoil = 0x0F,
  /*预制多个寄存器（设定多个寄存器的数值）*/
  ModbusFC_eWriteMultipleRegister  = 0x10,
  ModbusFC_eReadFileRecord         = 0x14, /*读文件记录*/
  ModbusFC_eWriteFileRecord        = 0x15, /*写文件记录*/
  ModbusFC_eMaskWriteRegister      = 0x16, /*屏蔽写寄存器*/
  ModbusFC_eReadWriteMultiRegister = 0x17, /*读写多个寄存器*/
  ModebusFC_eReadDeviceID          = 0x2B  /*读设备识别码*/
} FunctionCode;

/*定义接收到指令检测错误时的错误码*/
typedef enum {
  ModbusStatus_eOK                  = 0x00,
  ModbusStatus_eInvalidFunctionCode = 0x01,   //  不合法功能代码
  ModbusStatus_eIllegalDataAddress  = 0x02,   //  非法的数据地址
  ModbusStatus_eIllegalDataValues   = 0x03,   //  非法的数据值或者范围
  ModbusStatus_eSlaveFailure        = 0x04,   //  从站设备故障
  ModbusStatus_eAcknowledgement     = 0x05,   //  确认
  ModbusStatus_eSlaveDeviceBusy     = 0x06,   //  从属设备忙
  ModbusStatus_eMemoryParityError   = 0x08,   //  存储奇偶性差错
  ModbusStatus_eGatewayDisabled     = 0x0A,   //  不可用网关路径
  ModbusStatus_eGatewayResponseFailed = 0x0B  //  网关目标设备响应失败
} ModbusStatus;

struct ModBusRecvBuf {
  size_t  writerOffset_; /* offset from start of buffer where to write next */
  size_t  readOffset_;   /* offset from start of buffer where to read next */
  size_t  dataLength_;   /* offset from start of buffer where to read next */

  size_t  bufSize_; /* size of ring in bytes */
  uint8_t buf_[512];
};